package dao

import (
	"context"
	"fmt"
	"mini-app/internal/dal"
	"mini-app/internal/models"
	"strconv"
	"strings"

	"mini-app/config"

	"192.168.1.75/go-pkg/helper"
	"gorm.io/gorm"
)

type AdConfigDao struct{}

func (AdConfigDao) Create(ctx context.Context, query *dal.Query, name, value string) error {
	o := query.AdConfig

	ID, _ := helper.UUID{}.String()
	d := models.AdConfig{
		ID:    ID,
		Name:  name,
		Value: value,
	}
	return o.WithContext(ctx).Create(&d)
}

func (AdConfigDao) GetByIKey(ctx context.Context, query *dal.Query, name string) (models.AdConfig, error) {
	o := query.AdConfig
	tx := o.WithContext(ctx).Where(o.Name.Eq(name))
	res, err := tx.First()
	if err != nil {
		return models.AdConfig{}, err
	}
	return *res, nil
}

func (AdConfigDao) SetValueByID(ctx context.Context, query *dal.Query, key, value string) (err error) {
	if key == "" {
		return fmt.Errorf("invalid id")
	}
	tx := query.AdConfig.WithContext(ctx)
	tx = tx.Where(query.AdConfig.Name.Eq(key))
	tx.UpdateColumn(query.AdConfig.Value, value)
	return
}

func (AdConfigDao) SetBasePrice(ctx context.Context, query *dal.Query, basePrice float32) (err error) {
	tx := query.AdConfig.WithContext(ctx)
	tx = tx.Where(query.AdConfig.Name.Eq("BasePrice"))
	_, err = tx.First()
	if err == gorm.ErrRecordNotFound {
		err = AdConfigDao{}.Create(ctx, query, "BasePrice", fmt.Sprintf("%.2f", basePrice))
		return

	} else if err != nil {
		return err
	}

	// Update existing record
	tx.UpdateColumn(query.AdConfig.Value, fmt.Sprintf("%.2f", basePrice))
	return
}

func (AdConfigDao) GetBasePrice(ctx context.Context, query *dal.Query) (float32, error) {
	tx := query.AdConfig.WithContext(ctx)
	tx = tx.Where(query.AdConfig.Name.Eq("BasePrice"))
	adConfig, err := tx.First()
	if err != nil {
		if err == gorm.ErrRecordNotFound {

			basePrice := "19.9"
			if strings.Contains(config.Config.EnvType, "test") {
				basePrice = "0.01"
			}

			err = AdConfigDao{}.Create(ctx, query, "BasePrice", basePrice)
			if err != nil {
				return 0, err
			}

			tx = tx.Where(query.AdConfig.Name.Eq("BasePrice"))
			adConfig, err = tx.First()

		}
		if err != nil {
			return 0, err

		}
	}

	basePrice, err := strconv.ParseFloat(adConfig.Value, 32)
	if err != nil {
		return 0, err
	}

	return float32(basePrice), nil

}

func (AdConfigDao) SetSearchRadius(ctx context.Context, query *dal.Query, searchRadius float32) (err error) {
	tx := query.AdConfig.WithContext(ctx)
	tx = tx.Where(query.AdConfig.Name.Eq("SearchRadius"))
	_, err = tx.First()
	if err == gorm.ErrRecordNotFound {
		err = AdConfigDao{}.Create(ctx, query, "SearchRadius", fmt.Sprintf("%.2f", searchRadius))
		return

	} else if err != nil {
		return err
	}

	// Update existing record
	tx.UpdateColumn(query.AdConfig.Value, fmt.Sprintf("%.2f", searchRadius))
	return
}

func (AdConfigDao) GetSearchRadius(ctx context.Context, query *dal.Query) (float32, error) {
	tx := query.AdConfig.WithContext(ctx)
	tx = tx.Where(query.AdConfig.Name.Eq("SearchRadius"))
	adConfig, err := tx.First()
	if err != nil {
		if err == gorm.ErrRecordNotFound {

			searchRadius := "100.0"

			err = AdConfigDao{}.Create(ctx, query, "SearchRadius", searchRadius)
			if err != nil {
				return 0, err
			}

			tx = tx.Where(query.AdConfig.Name.Eq("SearchRadius"))
			adConfig, err = tx.First()

		}
		if err != nil {
			return 0, err

		}
	}

	searchRadius, err := strconv.ParseFloat(adConfig.Value, 32)
	if err != nil {
		return 0, err
	}

	return float32(searchRadius), nil

}
